home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 April: Mac OS SDK / Dev.CD Apr 98 SDK1.toast / Development Kits (Disc 1) / QuickDraw 3D / Documentation / d e v e l o p / Develop Issue 23 article / Geometry Sample / Headers / Exceptions.h < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-14  |  29.4 KB  |  1,019 lines  |  [TEXT/MPS ]

  1.  
  2. /*********************************************************************
  3.  
  4. FILENAME
  5.     Exceptions.h
  6.     
  7. DESCRIPTION
  8.     A collection of routines and macros to handle assertions and
  9.     exceptions.
  10.  
  11. COPYRIGHT
  12.     Copyright © Apple Computer, Inc. 1989-1991
  13.     All rights reserved.
  14.  
  15. ROUTINES
  16.     EXTERNALS
  17.         dprintf
  18.         check_dprintf
  19.         checkpos_dprintf
  20.  
  21. MACROS
  22.     EXTERNALS
  23.         check
  24.         ncheck
  25.         check_action
  26.         ncheck_action
  27.         require
  28.         nrequire
  29.         require_action
  30.         nrequire_action
  31.         resume
  32.  
  33. MODIFICATION HISTORY
  34.     08/03/89    Sean Parent
  35.         1)    Version 1.0d1 started
  36.     09/26/89    sp
  37.         1)    Corrected the description of require
  38.     12/08/89    sp
  39.         1)    Ported from XXXX Exceptions.h
  40.     03/16/90    sp
  41.         1)    Removed refCon parameter
  42.         2)    Added the "n" calls
  43.     05/10/90    sp
  44.         1)    Added the dprintf call and revved other macros to use it.
  45.     06/12/90    sp
  46.         1)    Modified the dprint off to use a macro for traceOption.
  47.     08/01/90    sp
  48.         1)    Modified for C++ compatibility (Thanks Ron).
  49.     08/14/90    sp
  50.         1)    Added action calls.
  51.     09/20/90    sp
  52.         1)    Removed rescue_ prefix in require exception labels.
  53.     01/16/91    sp
  54.         1)    Fixed some comments and updated the copyright notice.
  55.     02/13/91    sp
  56.         1)    Added check_action and ncheck_action calls.
  57.         2)    Added SetExceptionOption
  58.     02/22/91    sp
  59.         1)    Added {} around all macros just to be defensive for TED.
  60.         2)    Put everything in "if (true) { MACRO } else" form to be very
  61.             defensive.
  62.     02/26/91    sp
  63.         1)    Added a null statement after the else of each macro for the
  64.             fools who forgot to put ; in.
  65.     03/13/91    sp
  66.         1)    Added void* cast for privateAssertion for C++.
  67.     03/13/91    sp/NB
  68.         1)    Fixed void* cast for privateAssertion for C++.
  69.     11/04/91    sp
  70.         1)    Removed retry.
  71.         2)    Added DEBUGMIN support.
  72.         3) Removed SetExceptionOption.
  73.         4) Cleaned up for Develop article.
  74.     11/05/91    sp
  75.         1)    Removed PlaceHolder() and moved to "do { MACRO } while(false)"
  76.     11/19/91 sp
  77.         1)    Added DEBUGSYM level.
  78.         
  79. NOTE
  80.     To keep code size down, use these routines and macros with the C
  81.     compiler option -b2 or -b3. This will eliminate duplicate strings
  82.     within a procedure.
  83.  
  84. *********************************************************************/
  85.  
  86. #ifndef __EXCEPTIONS__
  87. #define __EXCEPTIONS__
  88.  
  89. /*********************************************************************
  90.  
  91. INCLUDES
  92.  
  93. *********************************************************************/
  94.  
  95. #ifndef    __TYPES__
  96. #include <Types.h>
  97. #endif
  98.  
  99. /*<FF>*/
  100. /*********************************************************************
  101.  
  102. CONSTANTS AND CONTROL
  103.  
  104. *********************************************************************/
  105.  
  106. /*
  107.     These defines are used to control the amount of information
  108.     displayed when an assertion fails. DEBUGOFF and WARN will run
  109.     silently. MIN will simply break into the debugger. ON will break
  110.     and display the assertion that failed and the exception (for
  111.     require statements). FULL will also display the source file name
  112.     and line number. SYM does a SysBreak and is usefull when using a
  113.     symbolic debugger like SourceBug or SADE. They should be set into
  114.     DEBUGLEVEL. The default LEVEL is OFF.
  115. */
  116.  
  117. #define DEBUGOFF        0
  118. #define DEBUGWARN        1
  119. #define DEBUGMIN        2
  120. #define DEBUGON        3
  121. #define DEBUGFULL        4
  122. #define DEBUGSYM        6
  123. #define DEBUGWINDOW        101
  124. #define DEBUGNICE        99
  125. #ifndef    DEBUGLEVEL
  126. #define    DEBUGLEVEL    DEBUGOFF
  127. #endif    DEBUGLEVEL
  128.  
  129. #if DEBUGLEVEL == DEBUGWINDOW
  130.     #include "wprintf.h"
  131. #endif
  132.  
  133.  
  134. /*
  135.     resumeLabel is used to control the insertion of labels for use with
  136.     the resume macro. If you do not use the resume macro and you wish
  137.     to have multible exceptions per label then you can add the
  138.     following define to you source code.
  139.     
  140.     #define resumeLabel(exception)
  141. */
  142.  
  143. #define resumeLabel(exception)    resume_ ## exception:
  144.  
  145. /*
  146.     trace and notrace are used for the traceOption for dprintf. If
  147.     trace is used then the actual behavior can be controled from
  148.     Macsbug. The macros in Macsbug are traceGo and traceBreak. traceGo
  149.     is the default and execution will continue after the break. If
  150.     traceBreak is used then execution will halt.
  151. */
  152.  
  153. #define    trace        "\p;dprintf;doTrace"
  154. #define    notrace    "\p;dprintf"
  155.  
  156. /*
  157.     traceon and debugon are used to test for options
  158. */
  159.  
  160. #define    traceon    ((DEBUGLEVEL > DEBUGWARN) && defined(TRACEON))
  161. #define    debugon    (DEBUGLEVEL > DEBUGWARN)
  162.  
  163. /*
  164.     Add some macros for DEBUGMIN and DEBUGSYM to keep the size down.
  165. */
  166.  
  167. #define    __DEBUGSMALL    ((DEBUGLEVEL == DEBUGMIN) ||            \
  168.                                  (DEBUGLEVEL == DEBUGSYM))
  169.  
  170. #if    DEBUGLEVEL == DEBUGMIN
  171. #define    __DebuggerBreak    Debugger()
  172. #elif    DEBUGLEVEL == DEBUGSYM
  173. #define  __DebuggerBreak    SysBreak()
  174. #endif
  175.  
  176. /*<FF>*/
  177. /*********************************************************************
  178.  
  179. ROUTINE
  180.     void dprintf(traceOption, format, ...)
  181.  
  182. DESCRIPTION
  183.     dprintf is used like printf only the information is displayed in
  184.     MacsBug. traceOption is used to specify whether the execution
  185.     should continue after the break or not. format contains
  186.     two types of objects: ordinary characters, which are displayed in
  187.     Macsbug, and coversion specifications, each of which causes
  188.     conversion and printing of the next successive argument to dprintf.
  189.     Each conversion specification begins with a % and ends with a
  190.     conversion character. Between % and the conversion character there
  191.     may be, in order:
  192.     
  193.     •    Zero or more flag characters, which modify the meaning of the
  194.         conversion specification.
  195.     •    A number that specifies the minimum field width. The converted
  196.         argument will be printed in a field at least this wide. If
  197.         necessary it will be padded on the left (or right, if left
  198.         adjustment is called for) to make up the field width.
  199.     •    A period, which separates the field width from the precision.
  200.     •    A number, the precision, that specifies the maximum number of
  201.         characters to be printed from a string, or the number of digits
  202.         after the decimal point of a floatingpoint value, or the minimum
  203.         number of digits for an integer.
  204.     •    An h if the integer is to be printed as a short, or l if as
  205.         long (ignored since int is long), or L to specify that the
  206.         following e, E, f, g, or G conversion is a long double.
  207.     
  208.     Note: A field width or precision may be indicated by an * instead
  209.     of a digit string. In this case, an integer arg parameter supplies
  210.     the field width or precision. The arg parameter that is actually
  211.     converted is not fetched until the conversion letter is seen;
  212.     therefore, the arg paramters specifying field width or precision
  213.     must appear immediately before the arg parameter (if any) to be
  214.     converted.
  215.     
  216.     The flag characters are:
  217.     
  218.         -        The result of the conversion will be left justified
  219.                 within the field.
  220.         +        The result of a signed conversion always begins with a
  221.                 sign (+ or -).
  222.         space    If the first character of a signed conversion is not a
  223.                 sign, a space will be prefixed to the result. This implies
  224.                 that if the space and + flags both appear, the space flag
  225.                 will be ignored.
  226.         #        The value is to be converted to an alternate form. For c,
  227.                 d, s, and u conversions, the flag has no effect. For o
  228.                 conversions, it increases the precision to force the first
  229.                 digit of the result to be zero. For x, and X conversions,
  230.                 a nonzero result will have 0x or 0X prefixed to it. For
  231.                 e, E, f, g, and G conversions, the result will always
  232.                 contain a decimal point, even if no digits follow the
  233.                 point. For g and G conversion, trailing zeros in the
  234.                 fractional part will not be removed from the result.
  235.         0        The 0 flag pads the field with zeros on the left only;
  236.                 this applies to d, i, o, u, x, X, e, E, f, g, and G
  237.                 conversions. The leading zeros pad the field width, and
  238.                 no space padding is performed. If both the 0 and - flags
  239.                 appear, the 0 flag is ignored. If a precision is specified
  240.                 for d, i, o, u, x, and X conversions, the 0 flag is
  241.                 ignored.
  242.     
  243.     The standard conversions are:
  244.     
  245.         d,i        int            Decimal number.
  246.         o        int            Unsigned octal number (w/o a leading zero).
  247.         x,X        int            Unsigned hexadecimal number (w/o a leading 0x
  248.                                 or oX), using abcdef or ABCDEF for 10,…,15.
  249.         u        int            Unsigned decimal number.
  250.         c        int            Single character.
  251.         s        char*            C string.
  252.         f        double        [-]m.dddddd, where the number of d's is given
  253.                                 by the precision (default 6).
  254.         e,E        double        [-]m.dddddde±xx or [-]m.ddddddE±xx, where the
  255.                                 number of d's is given by the precision
  256.                                 (default 6).
  257.         g,G        double        Use %e or %E if the exponent is less than -4
  258.                                 or greater than or equal to the precision;
  259.                                 otherwise use %f. Trailing zeros and a
  260.                                 trailing decimal point are not printed.
  261.         p        void*            Pointer.
  262.         %                        No argument is converted; print a %.
  263.     
  264.     The supported MPW extensions are:
  265.     
  266.         P        StringPtr    Pascal string.
  267.     
  268.     Of the MPW printf convertion characters only "n" is not supported.
  269.     In addition to the standard characters, the following are defined:
  270.     
  271.         b        Boolean        Outputs either true or false.
  272.         j        Point            Used like the d option.
  273.         J        point*        Fixed point. Used like the f option.
  274.         F        Fixed            Used like the f option.
  275.         T        Fract            Used like the f option.
  276.         r        Rect*            Displays the rect with each piece seperated by
  277.                                 ", ". Used like the d option.
  278.         R        rectangle*    Similar to r but for fixed point rectangles.
  279.                                 Used like the f option.
  280.         M        mapping.        Displays the mapping seperated by ", " and
  281.                                 "\n". The third column is displayed as fract.
  282.                                 Used like the f option.
  283.     
  284.         
  285.     dprintf requires that the MacsBug dcmd dprintf is present.
  286.     
  287.     Characters used:     bcdefghij l nop rs u  x
  288.                                 EFG  J LM  P R T   X
  289.     Not used:            a         k m   q  t vw yz
  290.                             ABCD   HI K  NO Q S UVW YZ
  291.     
  292.     See the MPW C Reference for more information on printf.
  293.  
  294. Echo "                                                            ∂n∂
  295.     PRINT            OFF,NOHDR                                    ∂n∂
  296.     INCLUDE        'Traps.a'                                    ∂n∂
  297.     PRINT            ON                                                ∂n∂
  298.     PROC                                                            ∂n∂
  299.     _DebugStr                                                    ∂n∂
  300.     SUBQ            #4,SP        ; Fix the stack                ∂n∂
  301.     ENDPROC                                                        ∂n∂
  302.     END                                                            ∂n∂
  303. " | Asm -l
  304.  
  305. *********************************************************************/
  306.  
  307. #if DEBUGLEVEL != DEBUGWINDOW
  308. void dprintf(StringPtr, char[], ...) = { 0xABFF, 0x594F };
  309. #endif
  310.  
  311.  
  312. /*<FF>*/
  313. /*********************************************************************
  314.  
  315. ROUTINE
  316.     void* check_dprintf(assertion, traceOption, format, ...)
  317.  
  318. DESCRIPTION
  319.     If assertion is non-zero then assertion is returned. Otherwise the
  320.     dprintf is invoked and zero is returned.
  321.     
  322. Echo "                                                            ∂n∂
  323.     PRINT            OFF,NOHDR                                    ∂n∂
  324.     INCLUDE        'Traps.a'                                    ∂n∂
  325.     PRINT            ON                                                ∂n∂
  326.     PROC                                                            ∂n∂
  327.     MOVE.L        (SP)+,D0    ; Pop value into D0            ∂n∂
  328.     BNE.S            @1            ; If !0 then branch            ∂n∂
  329.     _DebugStr                                                    ∂n∂
  330.     SUBQ            #4,SP        ; Fix the stack                ∂n∂
  331.     CLR.W            D0            ; Result is zero                ∂n∂
  332. @1    SUBQ            #4,SP        ; Fix stack for pop            ∂n∂
  333.     ENDPROC                                                        ∂n∂
  334.     END                                                            ∂n∂
  335. " | Asm -l
  336.     
  337. *********************************************************************/
  338.     
  339. #if DEBUGLEVEL != DEBUGWINDOW
  340. void* check_dprintf(void*, StringPtr, char[], ...) =
  341.     { 0x201F, 0x6606, 0xABFF, 0x594F, 0x4240, 0x594F };
  342. #endif    
  343. /*<FF>*/
  344. /*********************************************************************
  345.  
  346. ROUTINE
  347.     void* checkpos_dprintf(assertion, traceOption, format, ...)
  348.  
  349. DESCRIPTION
  350.     If assertion is positive then assertion is returned. Otherwise the
  351.     dprintf is invoked and zero is returned.
  352.     
  353. Echo "                                                            ∂n∂
  354.     PRINT            OFF,NOHDR                                    ∂n∂
  355.     INCLUDE        'Traps.a'                                    ∂n∂
  356.     PRINT            ON                                                ∂n∂
  357.     PROC                                                            ∂n∂
  358.     MOVE.L        (SP)+,D0    ; Pop value into D0            ∂n∂
  359.     BGE.S            @1            ; If >= 0 then branch        ∂n∂
  360.     _DebugStr                                                    ∂n∂
  361.     SUBQ            #4,SP        ; Fix the stack                ∂n∂
  362.     CLR.W            D0            ; Result is zero                ∂n∂
  363. @1    SUBQ            #4,SP        ; Fix stack for pop            ∂n∂
  364.     ENDPROC                                                        ∂n∂
  365.     END                                                            ∂n∂
  366. " | Asm -l
  367.     
  368. *********************************************************************/
  369.  
  370. #if DEBUGLEVEL != DEBUGWINDOW
  371. void* checkpos_dprintf(void*, StringPtr, char[], ...) =
  372.     { 0x201F, 0x6C06, 0xABFF, 0x594F, 0x4240, 0x594F };
  373. #endif
  374. /*<FF>*/
  375. /*********************************************************************
  376.  
  377. MACRO
  378.     check(assertion)
  379.  
  380. DESCRIPTION
  381.     If debugging is on then check will test assertion and if it fails
  382.     break into the debugger. Otherwise check does nothing.
  383.  
  384. *********************************************************************/
  385.  
  386. #if    __DEBUGSMALL
  387.  
  388. #define check(assertion)                                                            \
  389.     do {                                                                                    \
  390.         if (assertion) ;                                                                \
  391.         else __DebuggerBreak;                                                        \
  392.     } while (false)
  393.  
  394. #elif    DEBUGLEVEL == DEBUGON
  395.  
  396. #define check(assertion)                                                            \
  397.     do {                                                                                    \
  398.         if (assertion) ;                                                                \
  399.         else {                                                                            \
  400.             dprintf(notrace, "Assertion \"%s\" Failed",    #assertion);    \
  401.         }                                                                                    \
  402.     } while (false)
  403.  
  404. #elif    DEBUGLEVEL == DEBUGFULL
  405.  
  406. #define check(assertion)                                                            \
  407.     do {                                                                                    \
  408.         if (assertion) ;                                                                \
  409.         else {                                                                            \
  410.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  411.                                     "File: %s\n"                                        \
  412.                                     "Line: %d",                                            \
  413.                 #assertion, __FILE__, __LINE__);                                    \
  414.         }                                                                                    \
  415.     } while (false)
  416.  
  417. #elif    DEBUGLEVEL == DEBUGWINDOW
  418.  
  419. #define check(assertion)                                                            \
  420.     do {                                                                                    \
  421.         if (assertion) ;                                                                \
  422.         else {                                                                            \
  423.             wprintf(                "Assertion \"%s\" Failed\n"                    \
  424.                                     "File: %s\n"                                        \
  425.                                     "Line: %d\n",                                        \
  426.                 #assertion, __FILE__, __LINE__);                                    \
  427.         }                                                                                    \
  428.     } while (false)
  429.  
  430. #else
  431.  
  432. #define check(assertion)
  433.  
  434. #endif
  435.  
  436. /*<FF>*/
  437. /*********************************************************************
  438.  
  439. MACRO
  440.     ncheck(assertion)
  441.  
  442. DESCRIPTION
  443.     If debugging is on then ncheck will test !assertion and if it fails
  444.     break into the debugger. Otherwise ncheck does nothing.
  445.  
  446. *********************************************************************/
  447.  
  448. #if    __DEBUGSMALL
  449.  
  450. #define ncheck(assertion)                                                            \
  451.     do {                                                                                    \
  452.         if (assertion) __DebuggerBreak;                                            \
  453.     } while (false)
  454.  
  455. #elif    DEBUGLEVEL == DEBUGON
  456.  
  457. #define ncheck(assertion)                                                            \
  458.     do {                                                                                    \
  459.         void*    __privateAssertion    = (void*)(assertion);                    \
  460.                                                                                             \
  461.         if (__privateAssertion) {                                                    \
  462.             dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed",        \
  463.                 #assertion, __privateAssertion);                                    \
  464.         }                                                                                    \
  465.     } while (false)
  466.  
  467. #elif    DEBUGLEVEL == DEBUGFULL
  468.  
  469. #define ncheck(assertion)                                                            \
  470.     do {                                                                                    \
  471.         void*    __privateAssertion    = (void*)(assertion);                    \
  472.                                                                                             \
  473.         if (__privateAssertion) {                                                    \
  474.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  475.                                     "File: %s\n"                                        \
  476.                                     "Line: %d",                                            \
  477.             #assertion, __privateAssertion, __FILE__, __LINE__);            \
  478.         }                                                                                    \
  479.     } while (false)
  480.  
  481. #elif    DEBUGLEVEL == DEBUGWINDOW
  482.  
  483. #define ncheck(assertion)                                                            \
  484.     do {                                                                                    \
  485.         void*    __privateAssertion    = (void*)(assertion);                    \
  486.                                                                                             \
  487.         if (__privateAssertion) {                                                    \
  488.             wprintf(                "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  489.                                     "File: %s\n"                                        \
  490.                                     "Line: %d",                                            \
  491.             #assertion, __privateAssertion, __FILE__, __LINE__);            \
  492.         }                                                                                    \
  493.     } while (false)
  494.  
  495. #else
  496.  
  497. #define ncheck(assertion)
  498.  
  499. #endif
  500.  
  501. /*<FF>*/
  502. /*********************************************************************
  503.  
  504. MACRO
  505.     check_action(assertion, action)
  506.  
  507. DESCRIPTION
  508.     If debugging is on then check_action will test assertion and if it
  509.     fails break into the debugger then execute action. Otherwise
  510.     check_action does nothing.
  511.     
  512. *********************************************************************/
  513.  
  514. #if    __DEBUGSMALL
  515.  
  516. #define check_action(assertion, action)                                        \
  517.     do {                                                                                    \
  518.         if (assertion) ;                                                                \
  519.         else {                                                                            \
  520.             __DebuggerBreak;                                                            \
  521.             { action }                                                                    \
  522.     } while (false)
  523.  
  524. #elif    DEBUGLEVEL == DEBUGON
  525.  
  526. #define check_action(assertion, action)                                        \
  527.     do {                                                                                    \
  528.         if (assertion) ;                                                                \
  529.         else {                                                                            \
  530.             dprintf(notrace, "Assertion \"%s\" Failed",    #assertion);    \
  531.             { action }                                                                    \
  532.         }                                                                                    \
  533.     } while (false)
  534.  
  535. #elif    DEBUGLEVEL == DEBUGFULL
  536.  
  537. #define check_action(assertion, action)                                        \
  538.     do {                                                                                    \
  539.         if (assertion) ;                                                                \
  540.         else {                                                                            \
  541.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  542.                                     "File: %s\n"                                        \
  543.                                     "Line: %d",                                            \
  544.                 #assertion, __FILE__, __LINE__);                                    \
  545.             { action }                                                                    \
  546.         }                                                                                    \
  547.     } while (false)
  548.  
  549. #elif    DEBUGLEVEL == DEBUGWINDOW
  550.  
  551. #define check_action(assertion, action)                                        \
  552.     do {                                                                                    \
  553.         if (assertion) ;                                                                \
  554.         else {                                                                            \
  555.             wprintf(                "Assertion \"%s\" Failed\n"                    \
  556.                                     "File: %s\n"                                        \
  557.                                     "Line: %d",                                            \
  558.                 #assertion, __FILE__, __LINE__);                                    \
  559.             { action }                                                                    \
  560.         }                                                                                    \
  561.     } while (false)
  562.  
  563. #else
  564.  
  565. #define check_action(assertion, action)
  566.  
  567. #endif
  568.  
  569. /*<FF>*/
  570. /**************************************************************************************
  571.  
  572. MACRO
  573.     ncheck_action(assertion, action)
  574.  
  575. DESCRIPTION
  576.     If debugging is on then ncheck_action will test !assertion and if
  577.     it fails break into the debugger then execute action. Otherwise
  578.     ncheck_action does nothing.
  579.  
  580. *********************************************************************/
  581.  
  582. #if    __DEBUGSMALL
  583.  
  584. #define ncheck_action(assertion, action)                                        \
  585.     do {                                                                                    \
  586.         if (assertion) {                                                                \
  587.             __DebuggerBreak;                                                            \
  588.             { action }                                                                    \
  589.         }                                                                                    \
  590.     } while (false)
  591.  
  592. #elif    DEBUGLEVEL == DEBUGON
  593.  
  594. #define ncheck_action(assertion, action)                                        \
  595.     do {                                                                                    \
  596.         void*    __privateAssertion    = (void*)(assertion);                    \
  597.                                                                                             \
  598.         if (__privateAssertion) {                                                    \
  599.             dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed",        \
  600.                 #assertion, __privateAssertion);                                    \
  601.             { action }                                                                    \
  602.         }                                                                                    \
  603.     } while (false)
  604.  
  605. #elif DEBUGLEVEL == DEBUGFULL
  606.  
  607. #define ncheck_action(assertion, action)                                        \
  608.     do {                                                                                    \
  609.         void*    __privateAssertion    = (void*)(assertion);                    \
  610.                                                                                             \
  611.         if (__privateAssertion) {                                                    \
  612.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  613.                                     "File: %s\n"                                        \
  614.                                     "Line: %d",                                            \
  615.             #assertion, __privateAssertion, __FILE__, __LINE__);            \
  616.             { action }                                                                    \
  617.         }                                                                                    \
  618.     } while (false)
  619.  
  620. #elif DEBUGLEVEL == DEBUGWINDOW
  621.  
  622. #define ncheck_action(assertion, action)                                        \
  623.     do {                                                                                    \
  624.         void*    __privateAssertion    = (void*)(assertion);                    \
  625.                                                                                             \
  626.         if (__privateAssertion) {                                                    \
  627.             wprintf(                "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  628.                                     "File: %s\n"                                        \
  629.                                     "Line: %d",                                            \
  630.             #assertion, __privateAssertion, __FILE__, __LINE__);            \
  631.             { action }                                                                    \
  632.         }                                                                                    \
  633.     } while (false)
  634.  
  635. #else
  636.  
  637. #define ncheck_action(assertion, action)
  638.  
  639. #endif
  640.  
  641. /*<FF>*/
  642. /*********************************************************************
  643.  
  644. MACRO
  645.     require(assertion, exception)
  646.  
  647. DESCRIPTION
  648.     require will test assertion and if it fails:
  649.         break into the debugger if debugging is on.
  650.         goto exception.
  651.  
  652. *********************************************************************/
  653.  
  654. #if    __DEBUGSMALL
  655.  
  656. #define require(assertion, exception)                                            \
  657.     do {                                                                                    \
  658.         if (assertion) ;                                                                \
  659.         else {                                                                            \
  660.             __DebuggerBreak;                                                            \
  661.             goto exception;                                                            \
  662.             resumeLabel(exception);                                                    \
  663.         }                                                                                    \
  664.     } while (false)
  665.  
  666. #elif    DEBUGLEVEL == DEBUGON
  667.  
  668. #define require(assertion, exception)                                            \
  669.     do {                                                                                    \
  670.         if (assertion) ;                                                                \
  671.         else {                                                                            \
  672.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  673.                                     "Exception \"%s\" Raised",                        \
  674.             #assertion, #exception);                                                \
  675.             goto exception;                                                            \
  676.             resumeLabel(exception);                                                    \
  677.         }                                                                                    \
  678.     } while (false)
  679.  
  680. #elif DEBUGLEVEL == DEBUGFULL
  681.  
  682. #define require(assertion, exception)                                            \
  683.     do {                                                                                    \
  684.         if (assertion) ;                                                                \
  685.         else {                                                                            \
  686.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  687.                                     "Exception \"%s\" Raised\n"                    \
  688.                                     "File: %s\n"                                        \
  689.                                     "Line: %d",                                            \
  690.                 #assertion, #exception, __FILE__, __LINE__);                    \
  691.             goto exception;                                                            \
  692.             resumeLabel(exception);                                                    \
  693.         }                                                                                    \
  694.     } while (false)
  695.  
  696. #elif    DEBUGLEVEL == DEBUGWINDOW
  697. #define require(assertion, exception)                                            \
  698.     do {                                                                                    \
  699.         if (assertion) ;                                                                \
  700.         else {                                                                            \
  701.             wprintf(                "Assertion \"%s\" Failed\n"                    \
  702.                                     "Exception \"%s\" Raised\n"                    \
  703.                                     "File: %s\n"                                        \
  704.                                     "Line: %d\n",                                        \
  705.                 #assertion, #exception, __FILE__, __LINE__);                    \
  706.             goto exception;                                                            \
  707.             resumeLabel(exception);                                                    \
  708.         }                                                                                    \
  709.     } while (false)
  710.  
  711.  
  712. #else
  713.  
  714. #define require(assertion, exception)                                            \
  715.     do {                                                                                    \
  716.         if (assertion) ;                                                                \
  717.         else {                                                                            \
  718.             goto exception;                                                            \
  719.             resumeLabel(exception);                                                    \
  720.         }                                                                                    \
  721.     } while (false)
  722.  
  723. #endif
  724.  
  725. /*<FF>*/
  726. /*********************************************************************
  727.  
  728. MACRO
  729.     nrequire(assertion, exception)
  730.  
  731. DESCRIPTION
  732.     nrequire will test !assertion and if it fails:
  733.         break into the debugger if debugging is on.
  734.         goto exception.
  735.  
  736. *********************************************************************/
  737.  
  738. #if    __DEBUGSMALL
  739.  
  740. #define nrequire(assertion, exception)                                            \
  741.     do {                                                                                    \
  742.         if (assertion) {                                                                \
  743.             DebugStr();                                                                    \
  744.             goto exception;                                                            \
  745.             resumeLabel(exception);                                                    \
  746.         }                                                                                    \
  747.     } while (false)
  748.  
  749. #elif    DEBUGLEVEL == DEBUGON
  750.  
  751. #define nrequire(assertion, exception)                                            \
  752.     do {                                                                                    \
  753.         void*    __privateAssertion    = (void*)(assertion);                    \
  754.                                                                                             \
  755.         if (__privateAssertion) {                                                    \
  756.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  757.                                     "Exception \"%s\" Raised",                        \
  758.                 #assertion, __privateAssertion, #exception);                    \
  759.             goto exception;                                                            \
  760.             resumeLabel(exception);                                                    \
  761.         }                                                                                    \
  762.     } while (false)
  763.  
  764. #elif DEBUGLEVEL == DEBUGFULL
  765.  
  766. #define nrequire(assertion, exception)                                            \
  767.     do {                                                                                    \
  768.         void*    __privateAssertion    = (void*)(assertion);                    \
  769.                                                                                             \
  770.         if (__privateAssertion) {                                                    \
  771.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  772.                                     "Exception \"%s\" Raised\n"                    \
  773.                                     "File: %s\n"                                        \
  774.                                     "Line: %d",                                            \
  775.                 #assertion, __privateAssertion, #exception, __FILE__,        \
  776.                 __LINE__);                                                                \
  777.             goto exception;                                                            \
  778.             resumeLabel(exception);                                                    \
  779.         }                                                                                    \
  780.     } while (false)
  781.  
  782. #elif DEBUGLEVEL == DEBUGWINDOW
  783.  
  784. #define nrequire(assertion, exception)                                            \
  785.     do {                                                                                    \
  786.         void*    __privateAssertion    = (void*)(assertion);                    \
  787.                                                                                             \
  788.         if (__privateAssertion) {                                                    \
  789.             wprintf(                "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  790.                                     "Exception \"%s\" Raised\n"                    \
  791.                                     "File: %s\n"                                        \
  792.                                     "Line: %d",                                            \
  793.                 #assertion, __privateAssertion, #exception, __FILE__,        \
  794.                 __LINE__);                                                                \
  795.             goto exception;                                                            \
  796.             resumeLabel(exception);                                                    \
  797.         }                                                                                    \
  798.     } while (false)
  799.  
  800. #else
  801.  
  802. #define nrequire(assertion, exception)                                            \
  803.     do {                                                                                    \
  804.         if (assertion) {                                                                \
  805.             goto exception;                                                            \
  806.             resumeLabel(exception);                                                    \
  807.         }                                                                                    \
  808.     } while (false)
  809.  
  810. #endif
  811.  
  812. /*<FF>*/
  813. /*********************************************************************
  814.  
  815. MACRO
  816.     require_action(assertion, exception, action)
  817.  
  818. DESCRIPTION
  819.     require_action will test assertion and if it fails:
  820.         break into the debugger if debugging is on.
  821.         execute action.
  822.         goto exception.
  823.  
  824. *********************************************************************/
  825.  
  826. #if    __DEBUGSMALL
  827.  
  828. #define require_action(assertion, exception, action)                        \
  829.     do {                                                                                    \
  830.         if (assertion) ;                                                                \
  831.         else {                                                                            \
  832.             __DebuggerBreak;                                                            \
  833.             { action }                                                                    \
  834.             goto exception;                                                            \
  835.             resumeLabel(exception);                                                    \
  836.         }                                                                                    \
  837.     } while (false)
  838.  
  839. #elif    DEBUGLEVEL == DEBUGON
  840.  
  841. #define require_action(assertion, exception, action)                        \
  842.     do {                                                                                    \
  843.         if (assertion) ;                                                                \
  844.         else {                                                                            \
  845.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  846.                                     "Exception \"%s\" Raised",                        \
  847.             #assertion, #exception);                                                \
  848.             { action }                                                                    \
  849.             goto exception;                                                            \
  850.             resumeLabel(exception);                                                    \
  851.         }                                                                                    \
  852.     } while (false)
  853.  
  854. #elif DEBUGLEVEL == DEBUGFULL
  855.  
  856. #define require_action(assertion, exception, action)                        \
  857.     do {                                                                                    \
  858.         if (assertion) ;                                                                \
  859.         else {                                                                            \
  860.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  861.                                     "Exception \"%s\" Raised\n"                    \
  862.                                     "File: %s\n"                                        \
  863.                                     "Line: %d",                                            \
  864.                 #assertion, #exception, __FILE__, __LINE__);                    \
  865.             { action }                                                                    \
  866.             goto exception;                                                            \
  867.             resumeLabel(exception);                                                    \
  868.         }                                                                                    \
  869.     } while (false)
  870.  
  871. #elif DEBUGLEVEL == DEBUGWINDOW
  872.  
  873. #define require_action(assertion, exception, action)                        \
  874.     do {                                                                                    \
  875.         if (assertion) ;                                                                \
  876.         else {                                                                            \
  877.             wprintf(                "Assertion \"%s\" Failed\n"                    \
  878.                                     "Exception \"%s\" Raised\n"                    \
  879.                                     "File: %s\n"                                        \
  880.                                     "Line: %d",                                            \
  881.                 #assertion, #exception, __FILE__, __LINE__);                    \
  882.             { action }                                                                    \
  883.             goto exception;                                                            \
  884.             resumeLabel(exception);                                                    \
  885.         }                                                                                    \
  886.     } while (false)
  887.  
  888. #else
  889.  
  890. #define require_action(assertion, exception, action)                        \
  891.     do {                                                                                    \
  892.         if (assertion) ;                                                                \
  893.         else {                                                                            \
  894.             { action }                                                                    \
  895.             goto exception;                                                            \
  896.             resumeLabel(exception);                                                    \
  897.         }                                                                                    \
  898.     } while (false)
  899.  
  900. #endif
  901.  
  902. /*<FF>*/
  903. /*********************************************************************
  904.  
  905. MACRO
  906.     nrequire_action(assertion, exception, action)
  907.  
  908. DESCRIPTION
  909.     nrequire_action will test !assertion and if it fails:
  910.         break into the debugger if debugging is on.
  911.         execute action.
  912.         goto exception.
  913.  
  914. *********************************************************************/
  915.  
  916. #if    __DEBUGSMALL
  917.  
  918. #define nrequire_action(assertion, exception, action)                        \
  919.     do {                                                                                    \
  920.         if (assertion) {                                                                \
  921.             __DebuggerBreak;                                                            \
  922.             { action }                                                                    \
  923.             goto exception;                                                            \
  924.             resumeLabel(exception);                                                    \
  925.         }                                                                                    \
  926.     } while (false)
  927.  
  928. #elif DEBUGLEVEL == DEBUGON
  929.  
  930. #define nrequire_action(assertion, exception, action)                        \
  931.     do {                                                                                    \
  932.         void*    __privateAssertion    = (void*)(assertion);                    \
  933.                                                                                             \
  934.         if (__privateAssertion) {                                                    \
  935.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  936.                                     "Exception \"%s\" Raised",                        \
  937.                 #assertion, __privateAssertion, #exception);                    \
  938.             { action }                                                                    \
  939.             goto exception;                                                            \
  940.             resumeLabel(exception);                                                    \
  941.         }                                                                                    \
  942.     } while (false)
  943.  
  944. #elif DEBUGLEVEL == DEBUGFULL
  945.  
  946. #define nrequire_action(assertion, exception, action)                        \
  947.     do {                                                                                    \
  948.         void*    __privateAssertion    = (void*)(assertion);                    \
  949.                                                                                             \
  950.         if (__privateAssertion) {                                                    \
  951.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  952.                                     "Exception \"%s\" Raised\n"                    \
  953.                                     "File: %s\n"                                        \
  954.                                     "Line: %d",                                            \
  955.                 #assertion, __privateAssertion, #exception, __FILE__,        \
  956.                 __LINE__);                                                                \
  957.             { action }                                                                    \
  958.             goto exception;                                                            \
  959.             resumeLabel(exception);                                                    \
  960.         }                                                                                    \
  961.     } while (false)
  962.  
  963. #elif DEBUGLEVEL == DEBUGWINDOW
  964.  
  965. #define nrequire_action(assertion, exception, action)                        \
  966.     do {                                                                                    \
  967.         void*    __privateAssertion    = (void*)(assertion);                    \
  968.                                                                                             \
  969.         if (__privateAssertion) {                                                    \
  970.             wprintf(                "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  971.                                     "Exception \"%s\" Raised\n"                    \
  972.                                     "File: %s\n"                                        \
  973.                                     "Line: %d",                                            \
  974.                 #assertion, __privateAssertion, #exception, __FILE__,        \
  975.                 __LINE__);                                                                \
  976.             { action }                                                                    \
  977.             goto exception;                                                            \
  978.             resumeLabel(exception);                                                    \
  979.         }                                                                                    \
  980.     } while (false)
  981.  
  982. #else
  983.  
  984. #define nrequire_action(assertion, exception, action)                        \
  985.     do {                                                                                    \
  986.         if (assertion) {                                                                \
  987.             { action }                                                                    \
  988.             goto exception;                                                            \
  989.             resumeLabel(exception);                                                    \
  990.         }                                                                                    \
  991.     } while (false)
  992.  
  993. #endif
  994.     
  995. /*<FF>*/
  996. /*********************************************************************
  997.  
  998. MACRO
  999.     resume(exception)
  1000.  
  1001. DESCRIPTION
  1002.     resume will resume execution after the n/require/_action statement
  1003.     specified by exception. Resume lables must be on (the default) in
  1004.     order to use resume. If an action form of require was used then the
  1005.     action will not be re-executed.
  1006.  
  1007. *********************************************************************/
  1008.  
  1009.  
  1010. #define resume(exception)                                                            \
  1011.     do {                                                                                    \
  1012.         goto resume_ ## exception;                                                    \
  1013.     } while (false)
  1014.  
  1015.  
  1016. /*<FF>*/
  1017. /********************************************************************/
  1018.  
  1019. #endif